﻿var Array = require('./ArrayExt');
var Promise = require('bluebird');
var mongoose = require('mongoose');
var WOvertimeMdl = require('../module/work_overtime');


/**
 * 根据月份拆分数据,输出重组后的Map{month:number,addDates:[]},rmDates:[]}对象
 * @param markDates 需要checkIn的日期字符串数组
 * @param rmDates 需要移除的日期字符串数组
 */
function anaylizeDates(markDates, rmDates) {
    var updMonths = new Map();
    /**
     * 根据月份拆分数据
     */
    markDates.forEach(function (element, index, array) {
        var checkInDate = new Date(element);
        var month = checkInDate.getMonth() + 1;
        if (updMonths.get(month)) {
            updMonths.get(month).addDates.push(element);
        } else {
            updMonths.set(month, { addDates: [element], rmDates: [] });
        }
    });
    rmDates.forEach(function (element, index, array) {
        var removeMarkedDate = new Date(element);
        var month = removeMarkedDate.getMonth() + 1;
        if (updMonths.get(month)) {
            updMonths.get(month).rmDates.push(element);
        } else {
            updMonths.set(month, { addDates: [], rmDates: [element] });
        }
    });

    return updMonths;
}

/**
 * 接受查询条件返回<查询Promise>，then 处理查询的结果集
 * @param condition 查询条件
 */
var queryPromise = function (condition) {
    return new Promise(function (fulfill, reject) {
        WOvertimeMdl.find(condition, function (err, res) {
            if (err) { reject(err); }
            else { fulfill(res); }
        });
    });
};

/**
 * 接受docs或null返回<新增或修改Promise>, then 处理保存后数据库返回的修改结果集
 * @param doc
 * @param newData 需要更新的信息{emp_name:,emp_no:,month:,markDate:,fare:,department_name:,position:}
 */
var createOrUpdatePromise = function (doc, newData) {
    return new Promise(function (fulfill, reject) {
        // 收到结果集，update结果集
        if (doc) {
            if (!doc instanceof Array) {
                doc.overtime_date = newData.markDate;
                doc.fare = newData.fare;
                doc.save(function (err, res) {
                    if (err) { reject(err); }
                    else { fulfill(res); }
                });
            } else if (doc.length > 1) {
                console.error('无法建立映射关系，不能处理多于1条记录的docs对象');
                reject(new Error('系统错误，获取多条对应记录！'));
            } else if (doc.length == 1) {
                doc = doc[0];
                doc.overtime_date = newData.markDate;
                doc.fare = newData.fare;
                doc.save(function (err, res) {
                    if (err) { reject(err); }
                    else { fulfill(res); }
                });
            } else {
                WOvertimeMdl.create({
                    employee_name: newData.emp_name,
                    employee_no: newData.emp_no,
                    month: newData.month,
                    department_name: newData.department_name,
                    position: newData.position,
                    overtime_date: newData.markDate,
                    fare: newData.fare
                }, function (err, res) {
                    if (err) { reject(err); }
                    else { fulfill(res); }
                });
            }
        } else {
            WOvertimeMdl.create({
                employee_name: newData.emp_name,
                employee_no: newData.emp_no,
                month: newData.month,
                department_name: newData.department_name,
                position: newData.position,
                overtime_date: newData.markDate,
                fare: newData.fare
            }, function (err, res) {
                if (err) { reject(err); }
                else { fulfill(res); }
            });
        }
    });
};

var delPromise = function (condition) {
    return new Promise(function (fulfill, reject) {
        WOvertimeMdl.remove(condition, function (err) {
            if (err) { reject(err); }
            else { fulfill(condition);}
        });
    });
};

var checkInCtller = new Object();

checkInCtller.QueryByEmpnoMonth = function (emp_no, month, callback) {
    queryPromise({ employee_no: emp_no, month: month })
        .then(function (res) {
            console.log("get query rst:", JSON.stringify(res));
            if (res instanceof Array) {
                var data = {};
                res.forEach(function (v, i, ar) {
                    if (i == 0) {
                        data.employee_name = v.employee_name;
                        data.employee_no = v.employee_no;
                        data.department_name = v.department_name;
                        data.position = v.position;
                        data.month = v.month;
                        data.markDates = [[v.overtime_date, v.fare]];
                    }
                    else {
                        data.markDates.push([v.overtime_date, v.fare]);
                    }
                });
                callback(null, data);
            }
            else { callback(new TypeError("查询结果不是预期的docs对象"), res); }
        })
        .catch(function (reason) {
            console.log("mongodb query err:", reason);
            callback(reason, null);
        });
}
checkInCtller.CheckInMarkDates = function (userObj, markDates, rmDates, callback) {
    var promises = [];
    
    markDates.forEach(function (v, i, m) {
        var checkInDate = new Date(v[0]);
        var month = checkInDate.getMonth() + 1;
        promises
            .push(queryPromise({ employee_no: userObj.employee_no, overtime_date: v[0] })
                .then(function (res) {
                    var newData = {
                        emp_name: userObj.employee_name,
                        emp_no: userObj.employee_no,
                        month: month,
                        markDate: v[0],
                        fare: v[1],
                        department_name: userObj.department_name,
                        position: userObj.position
                    };
                    return createOrUpdatePromise(res, newData);
                }));
    });

    rmDates.forEach(function (v, i, ar) {
        promises.push(delPromise({ employee_no: userObj.employee_no, overtime_date: v }));
    });

    Promise.all(promises)
        .then(function (values) {
            console.log("mongodb update finish:", JSON.stringify(values));
            callback(null,values);
        })
        .catch(function (reason) {
            console.log("mongodb update err:", reason);
            callback(reason, null);
        });
}

module.exports = checkInCtller;